package com.zx.util;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.zx.annotation.DataClass;
import com.zx.converter.base.IntegerConverter;
import com.zx.exception.DataParseException;
import com.zx.model.HandlerArgs;
import com.zx.process.AbstractProcessHandler;
import com.zx.process.ProcessHandler;

/**
 * @Project: dataParse-core
 * @Title: DataFieldProcessHandler
 * @Description: 类(针对一行数据)--处理器--工厂
 * @author: xue.zhang
 * @date: 2019年1月14日上午11:52:24
 * @company: alibaba
 * @Copyright: Copyright (c) 2017
 * @version v1.0
 */
public class DataClassProcessHandlerFactory {
	
	public static <T> ProcessHandler getProcessHandler(Class<T> clazz) throws DataParseException {
		DataClass dataConfig = clazz.getAnnotation(DataClass.class);
		if(dataConfig == null) {
			throw new DataParseException("class" + clazz + "没有配置字段注解@DataClass");
		}
		
		LineDataLengthCheckedHandler handler = new LineDataLengthCheckedHandler(dataConfig.lineDataLength());
		handler.setNextHandler(null);
		return handler;
	}
	
	/**
	 * @Project: dataParse-core
	 * @Title: LineDataLengthCheckedHandler
	 * @Description: 一行数据切割后column的数量,默认是0，不校验
	 * @author: xue.zhang
	 * @date: 2019年1月14日下午7:46:21
	 * @company: alibaba
	 * @Copyright: Copyright (c) 2017
	 * @version v1.0
	 */
	public static class LineDataLengthCheckedHandler extends AbstractProcessHandler {
		
		private static Logger logger = LoggerFactory.getLogger(LineDataLengthCheckedHandler.class);
		
		private int lineDataLength;
		
		IntegerConverter integerConverter = new IntegerConverter();
		
		public LineDataLengthCheckedHandler(int lineDataLength) {
			this.lineDataLength = lineDataLength;
		}

		/**
		 * 这里传入的值是数组的长度
		 * @throws DataParseException 
		 */
		@Override
		public boolean handler(HandlerArgs args) {
			Object column = args.getObj();
			Integer length;
			try {
				length = integerConverter.convertValue(column);
			} catch (DataParseException e) {
				throw new RuntimeException("传入的数组长度异常", e); 
			}
			boolean bool = (lineDataLength == 0) ?  true : lineDataLength == length;
			// 本次处理未通过，直接返回
			if(bool) {
				return this.handlerNext(args);
			} else {
				logger.info("校验失败, 数据切割后column的数量设置lineDataLength={}, 实际={}", lineDataLength, length);
				return false;
			}
		}
	}
	
}
